package com.xul.crowd.controller;

import com.xul.crowd.api.MysqlRemoteService;
import com.xul.crowd.api.RedisRemoteService;
import com.xul.crowd.config.ShortMessageProperties;
import com.xul.crowd.constant.CrowdConstant;
import com.xul.crowd.util.CrowdUtil;
import com.xul.crowd.util.ResultEntity;
import com.xul.entity.po.MemberPO;
import com.xul.entity.vo.MemberLoginVo;
import com.xul.entity.vo.MemberVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author xul
 * @create 2021-07-29 13:00
 */
@Controller
public class MemberController {

    @Autowired
    private ShortMessageProperties shortMessageProperties;

    @Autowired
    private RedisRemoteService redisRemoteService;

    @Autowired
    private MysqlRemoteService mysqlRemoteService;


    /**
     * 会员注册验证码到redis
     *
     * @param phoneNum
     * @return
     */
    @ResponseBody
    @RequestMapping("auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam String phoneNum) {
        // 拼接一个用于在Redis中存储数据的key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        // 判断redis里面有么有验证码 有验证码的话 就不重新发送短信
        ResultEntity<String> redisResult = redisRemoteService.getRedisStringValueByKeyRemote(key);
        String redisData = redisResult.getData();
        if (!StringUtils.isEmpty(redisData)) {
            return ResultEntity.successWithData();
        }

        // 1.发送验证码到手机
        ResultEntity<String> codeByShortMessage = CrowdUtil.sendCodeByShortMessage(
                shortMessageProperties.getHost(),
                shortMessageProperties.getPath(),
                shortMessageProperties.getMethod(),
                phoneNum,
                shortMessageProperties.getAppcode(),
                shortMessageProperties.getSign(),
                shortMessageProperties.getSkin()
        );
        // 2.判断短信发送结果
        if (ResultEntity.SUCCESS.equals(codeByShortMessage.getResult())) {
            // 3.如果发送成功 则将验证码存入到Redis中
            // 从上一步操作的结果中获取随机生成的验证码
            String code = codeByShortMessage.getData();

            // 调用远程的redis
            ResultEntity<String> saveCodeResult = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
            // 判断结果
            if (ResultEntity.SUCCESS.equals(saveCodeResult.getResult())) {
                return ResultEntity.successWithData();
            } else {
                return saveCodeResult;
            }
        } else {
            return codeByShortMessage;
        }
    }

    /**
     * 会员注册接口
     *
     * @param memberVO
     * @param modelMap
     * @return
     */
    @RequestMapping("auth/do/member/register.html")
    public String register(MemberVO memberVO, ModelMap modelMap) {
        // 1.获取用户的手机号
        String phoneNum = memberVO.getPhoneNum();
        // 2.拼接Redis中存储验证码到key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        // 3.从Redis读取key对应的value的值
        ResultEntity<String> redisResult = redisRemoteService.getRedisStringValueByKeyRemote(key);
        // 4.检查查询是否有效
        String result = redisResult.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, redisResult.getMessage());
            return "member-reg";
        }
        String redisData = redisResult.getData();
        if (redisData == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXITS);
            return "member-reg";
        }
        // 5.如果能从redis中查询到表单的验证码就和表单中的验证码经行比较
        String formCode = memberVO.getCode();
        if (!Objects.equals(formCode, redisData)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
        // 6.如果验证码一致,就从Redis中删除验证码
        redisRemoteService.removeRedisKeyRemote(key);
        // 7.执行密码的加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String userpswdBeforeEncode = memberVO.getUserpswd();
        String userpswdAfterEncode = passwordEncoder.encode(userpswdBeforeEncode);
        memberVO.setUserpswd(userpswdAfterEncode);
        // 8.执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);
        ResultEntity<String> saveResult = mysqlRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(saveResult.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveResult.getMessage());
            return "member-reg";
        }
        // 使用重定向避免刷新浏览器导致重新注册流程
        return "redirect:http://localhost:/auth/member/to/login/page.html";
    }

    /**
     * 会员登录接口
     *
     * @param loginacct
     * @param userpswd
     * @param modelMap
     * @param session
     * @return
     */
    @RequestMapping("auth/member/do/login.html")
    public String login(String loginacct, String userpswd, ModelMap modelMap, HttpSession session) {
        // 1.调用远程接口根据登录账号查询MemberPO得对象
        ResultEntity<MemberPO> memberPOBResult = mysqlRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if (ResultEntity.FAILED.equals(memberPOBResult.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, memberPOBResult.getMessage());
            return "member-login";
        }
        MemberPO memberPO = memberPOBResult.getData();
        if (memberPO == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }

        // 2.比较密码
        String userpswdDataBase = memberPO.getUserpswd();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(userpswd, userpswdDataBase);
        if (!matches) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        // 3.创建MemberLoginVO对象存入到Session中
        MemberLoginVo memberLoginVo = new MemberLoginVo(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVo);

       /* MemberLoginVo memberLoginVo1 = (MemberLoginVo) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
        System.out.println(memberLoginVo1.toString());*/

        return "redirect:http://localhost:/auth/member/to/center/page.html";
    }

    /**
     * 会员登出
     *
     * @param session
     * @return
     */
    @RequestMapping("auth/member/logout.html")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:http://localhost:/";
    }
}
